package crap;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;

import org.ejml.simple.SimpleMatrix;

public class CTester01 {
	public static void main(String[] args) throws Exception {
//		final BufferedImage bi = ImageIO.read(CTester01.class.getClassLoader().getResourceAsStream("res/P5100207s.JPG"));
		final BufferedImage bi = ImageIO.read(CTester01.class.getClassLoader().getResourceAsStream("res/P5100210s.JPG"));

		final Point2D[] camPoints = {new Point2D.Double(400,160), new Point2D.Double(464,344), new Point2D.Double(167,393), new Point2D.Double(119, 191)};
		final Point2D[] A4Points = {new Point2D.Double(0, 0), new Point2D.Double(0.210, 0), new Point2D.Double(0.210, 0.297), new Point2D.Double(0, 0.297)};
		final Path2D markerLine = new Path2D.Double();

		markerLine.moveTo(camPoints[0].getX(), camPoints[0].getY());
		markerLine.lineTo(camPoints[1].getX(), camPoints[1].getY());
		markerLine.lineTo(camPoints[2].getX(), camPoints[2].getY());
		markerLine.lineTo(camPoints[3].getX(), camPoints[3].getY());
		markerLine.closePath();
		
		JFrame ff = new JFrame();
		ff.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		final JComponent canvas = new JComponent() {
			{setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight()));}
			@Override
			public void paint(Graphics g) {
				Graphics2D g2 = (Graphics2D)g;
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
				g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
				g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
				
				g2.drawImage(bi, 0, 0, this);
				g2.setStroke(new BasicStroke(2f));
				g2.setColor(Color.red);
				g2.draw(markerLine);
				
				super.paint(g);
			}
		};
		
		MouseListener ml = new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				System.out.println(e.getPoint());
				super.mouseClicked(e);
			}
		};
		canvas.addMouseListener(ml);
		
		SimpleMatrix leftSide = new SimpleMatrix(8, 8), rightSide = new SimpleMatrix(8, 1);
		
		
		for (int i = 0; i<4; i++) {
			
			double x = A4Points[i].getX(), y = A4Points[i].getY(), x_ = camPoints[i].getX(), y_ = camPoints[i].getY();
			//x_ = (x y 1 0 0 0 -x_*x -x_*y ) h = x_
			leftSide.set(i*2, 0, x);
			leftSide.set(i*2, 1, y);
			leftSide.set(i*2, 2, 1);

			leftSide.set(i*2, 3, 0);
			leftSide.set(i*2, 4, 0);
			leftSide.set(i*2, 5, 0);
			
			leftSide.set(i*2, 6, -x_*x);
			leftSide.set(i*2, 7, -x_*y);
			
			//y_ = (0 0 0 x y 1 -y_*x -y_*y) h = y_
			leftSide.set(i*2+1, 0, 0);
			leftSide.set(i*2+1, 1, 0);
			leftSide.set(i*2+1, 2, 0);

			leftSide.set(i*2+1, 3, x);
			leftSide.set(i*2+1, 4, y);
			leftSide.set(i*2+1, 5, 1);
			
			leftSide.set(i*2+1, 6, -y_*x);
			leftSide.set(i*2+1, 7, -y_*y);
			
			// x_ und y_ im Ergebnisvektor setzen 
			rightSide.set(i*2, 0, x_);
			rightSide.set(i*2+1, 0, y_);
		}
		
		System.out.println(leftSide);
		System.out.println(rightSide);
		
		SimpleMatrix h = leftSide.solve(rightSide);
		System.out.println(leftSide.svd().getW());
		double h11 = h.get(0, 0), h12 = h.get(1,0), h13 = h.get(2, 0), h21 = h.get(3, 0), h22 = h.get(4, 0), h23 = h.get(5, 0), h31 = h.get(6, 0), h32 = h.get(7, 0);
		double lambda1 = Math.sqrt(h11*h11+h21*h21+h31*h31), lambda2 = Math.sqrt(h12*h12+h22*h22+h32*h32);
		System.out.println("lambda1: "+lambda1+"   lambda2: "+lambda2);
		double lambda = Math.max(lambda1, lambda2);
		
		System.out.println(h);
		
		ff.add(canvas);
		
		ff.pack();
		ff.setVisible(true);
		
	}
}
